/***********************************************************************
       _                                       
 _ __ (_)_ __   ___  ___ ___  _ __   ___   ___ 
| '_ \| | '_ \ / _ \/ __/ _ \| '_ \ / _ \ / __|
| |_) | | | | |  __/ (_| (_) | | | |  __/| (__ 
| .__/|_|_| |_|\___|\___\___/|_| |_|\___(_)___|
|_|                                            
pinecone.c
Mark Bolding 9/2006
and a cast of thousands
Yun Jiang
D Twieg
R Deshpande
Maj Hedehus
etc.

adapted from Rose.c adapted from episs.c
waveforms are now pre-computed externally in matlab or your favorite enviroment
 *
 * revised 6 dec 2006 -- msb 
 * remove more unused variables
 * clean up the formatting
 * add diagnostic ouput

crose: circumscribed rosette, gradient amplitude of 4.6833
lowg_crose: circumscribed rosette, gradient amplitude of 3.64272
irose: inscribed rosette, gradient amplitude of 4.68246
lowg_irose: inscribed rosette, gradient amplitude of 3.64312

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
     _                       __                                 __     _
    |                       |                                     |     |
RF  | -----[alpha]----------|---------------- |** ACQ **|---------|     |
    |                       |                                     |     |
    |          < - - - - - -|- -esp - - - - - - - >               |     |
    |        ____           |                                     |     |
GSS | ______/////\     _____|_____________________________________|     |
    | <---->      \\\\/ gssr|                                     |     |
    |   predelay  <--> tref |                                     | etl | ns
    |                       |                                     |     |
    |                       |                                     |     |
GPE |  _____________________|______________/\_____________________|     |
    |                       |              \/                     |     |
    |                       |                                     |     |
    |                       |                  _________          |     |
GRO |  ___________     _____|_________________//////////\_________|     |
    |             \\\\/     |                                     |     |
    |_                      |__                                 __|    _|

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#include "standard.h"
#include "group.h"
#define MAX_DAC_VAL  32767.0  /* maximum DAC value for system*/

pulsesequence()
{
    /* INTERNAL VARIABLE DECLARATIONS *********************/
    double  sedelay,predelay,seqtime;
    double  agss,grate,gssrint;
    double  rgss,rgssr;
    double  ted,ted1,ted2,tssr;
    double	agssr,sattime;
    char   	calib[MAXSTR],ro_shape[MAXSTR], pe_shape[MAXSTR],fatsat[MAXSTR];
    char   	spinecho[MAXSTR],crose_ro[MAXSTR], crose_pe[MAXSTR], *home_dir;    
    
    initparms_sis();
    getstr("fatsat", fatsat);	/*fat saturation*/ 
    getstr("calib",calib);		/* for slice selctive cal with big phantoms */    							
    getstr("spinecho",spinecho);/* spin echo/gradient echo flag */
    /* gro=4.6833;			/* amplitude of rosette waveform */
    grate = trise/gmax;			/* gradient rate */
    agss = fabs(gss);			/* absolute val of slice sel gradient */
    rgss = grate*agss;			/* slice select gradient rate */

  	/* GRADIENT*TIME INTEGRALS FOR SLICE SELECTION, PHASE AND READOUT */
    gssrint = agss*(p1/2.0 + rof2 + rgss/2.0);
    gssr = gss;
    gssr = gssr*gssf;
    agssr = fabs(gssr);
    rgssr = grate*agssr;
    tssr = gssrint/agssr; /* slice refocussing time for constant pulse */
    tssr = tssr - rgssr;  /* correct for ramps */
	if ((home_dir = (char *) getenv("HOME")) == NULL) {
		abort_message("Error in determining HOME environment variable\n");
	}	
    getstr("ro_shape",ro_shape); 
    getstr("pe_shape",pe_shape);
	sprintf(crose_ro, "%s/vnmrsys/shapelib/%s.GRD",home_dir,ro_shape);
	sprintf(crose_pe, "%s/vnmrsys/shapelib/%s.GRD",home_dir,pe_shape);

  	/* RELAXATION DELAY */
	seqtime = rgss + rof1 + p1 + rof2 + rgssr*2 + tssr + at;
	
	if (spinecho[0] == 'y') {
		/* second half echo time */
		ted2 = at/2.0 + tspoil + p2/2.0 + rof2 + rgss;
		/* first half, event time */
		ted1 = p1/2.0 + rof2 + rgss*2 + tssr + rgssr*2; 
		ted = ted2 - ted1;  /* buffer delay if spin echo */
		sedelay = ted + rof1 + p2 + rof2 + (rgss*2) + (tspoil*2); 
		seqtime = seqtime + sedelay;
	}
	else {
		ted = 0;
	}
	
	sattime  = rof1 + psat + rof2 + tcrush + trise;
	if (fatsat[0] == 'y') 
		seqtime = seqtime + sattime; 	/* add in fat saturation time */	
	
	if (tr - seqtime < 0.0) {
		abort_message("%s: Requested tr too short. Min tr = %f ms",
		seqfil,seqtime*1e3);
	}
	predelay = (tr - seqtime);
    
    if (verbose[0] == 'y') { /* print test information */
        printf("*********** %s ************************************\n",seqfil);
        printf("gradient files\n ro: %s\n pe: %s\n", crose_ro, crose_pe);
        printf("calibration setting: %s\n", calib);
        printf("gro: %.3e\n", gro);
        printf("gpe: %.3e\n", gpe);
        printf("gss: %.3e\n", gss);
        printf("gssr: %.3e\n", gssr);
        printf("at: %.9f ms\n", at*1000);
        printf("***************************************************\n");

    }
  
  	/* PULSE SEQUENCE *************************************/
    /* Relaxation delay ***********************************/       
    status(A);
    /* Phase cycle: Part I ********************************/
    mod2(ct,v3);                    /*0101 0101*/
    dbl(v3,v3);                     /*0202 0202*/
    hlv(ct,v4);                     /*0011 2233*/
    mod2(v4,v4);                    /*0011 0011*/
    add(v3,v4,v1);                  /*0213 0213*/
    assign(v1,oph);
    add(one,v1,v2);
    assign(zero,v10);
    assign(zero,v12);
    
	delay(predelay);       
	msloop(seqcon[1],ns,v13,v14); /**********************************/       
		rotate();              
		/* fat saturation pulse *******************************/
		if (fatsat[0] == 'y') {
			obspower(satpwr);
			obsoffset(resto-(3.4*sfrq));
			shapedpulse(satpat,psat,zero,rof1,rof2);
			obl_gradient(gcrush,gcrush,gcrush);
			delay(tcrush);
			zero_all_gradients();
			delay(trise);
			obsoffset(resto);
		}      
		/* Gating *********************/
		xgate(ticks);
		poffset_list(pss,gss,ns,v14);  /* set slice offset frequency */	
		if (ir[0] == 'y')
		{
			/* 180 degree RF pulse *****************************/
			obspower(tpwr2);
			obsoffset(resto);
			obl_gradient(0.0,0.0,gss);
			delay(rgss);
			delay(tspoil);
			shapedpulse(p2pat,p2,v2,rof1,rof2);
			delay(tspoil);
			zero_all_gradients();
			delay(rgss);		
			delay(ti-tspoil-rgss-p2/2);
		}
		/* 90 degree RF excitation pulse ****************************/ 
		observepower(tpwr1);		
		if (calib[0] == 'r') obl_gradient(gss,0.0,0.0);
		if (calib[0] == 'p') obl_gradient(0.0,gss,0.0);
		if (calib[0] == 'n') obl_gradient(0.0,0.0,gss);
		delay(rgss);
		shapedpulse(p1pat,p1,v1,rof1,rof2); /* exciting event */
		zero_all_gradients();
		delay(rgss);	
		/* Read & Slice refocus and phase encode pulse ********/
		if (calib[0] == 'r') obl_gradient(-gssr,0.0,0.0);
		if (calib[0] == 'p') obl_gradient(0.0,-gssr,0.0);
		if (calib[0] == 'n') obl_gradient(0.0,0.0,-gssr);
		delay(rgssr);
		delay(tssr);
		zero_all_gradients();
		delay(rgssr);
		/* 180 degree refocus RF pulse *****************************/
		if (spinecho[0] == 'y')
		{
			/* delay(ted); */
			acquire(1.0*ted/sw,1./sw); /* aquire data from fid before spin echo */
			obspower(tpwr2);
			if (calib[0] == 'r') obl_gradient(gss,0.0,0.0);
			if (calib[0] == 'p') obl_gradient(0.0,gss,0.0);
			if (calib[0] == 'n') obl_gradient(0.0,0.0,gss);
			delay(rgss);
			delay(tspoil);
			shapedpulse(p2pat,p2,v2,rof1,rof2);
			delay(tspoil);
			zero_all_gradients();
			delay(rgss);
		}
		if (calib[0] == 'r') obl_shapedgradient("crose_ro","","",at,gro,0.0,0.0,1,NOWAIT);
		if (calib[0] == 'p') obl_shapedgradient("","crose_pe","",at,0.0,gpe,0.0,1,NOWAIT);
		if (calib[0] == 'n') 
        {
            poffset(pro,gro);
            obl_shapedgradient("crose_ro","crose_pe","",at,gro,gpe,0.0,1,NOWAIT);
        }
		obsoffset(resto);
		acquire(np,1./sw);   /* show me the data! */
		zero_all_gradients();
	endmsloop(seqcon[1],v14);
}
